package com.woniu.smart.config;

import io.swagger.models.auth.In;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Description: swagger配置文件
 * @Author: WangHeng
 * @Date: 2022/10/25 14:14
 */
@Configuration
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        // 指定swagger3.0版本
        return new Docket(DocumentationType.OAS_30)
                .groupName("smartPark")
                // 设置哪些接口暴露给Swagger展示
                .select()
                // 扫描指定包中的swagger注解
                // 指定扫描的包 常用方式
                .apis(RequestHandlerSelectors.basePackage("com.woniu.smart.controller"))
                // 扫描所有包中所有的swagger注解
                .paths(PathSelectors.any())
                .build()
                // 支持的通讯协议集合
                .protocols(newHashSet("https", "http"))
                //文档的开关
                .apiInfo(createApiInfo())
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }


    @Bean
    public ApiInfo createApiInfo() {
        return new ApiInfo(
                //标题
                "智慧园区Api文档",
                //描述
                "智慧园区smart项目Api文档详细说明",
                //版本
                "1.0",
                //团队链接
                "https://www.woniuxy.com",
                new Contact("smart", "https://www.woniuxy.com", "1011945095@qq.com"),
                "Apache 2.0",
                "https://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList());
    }

    /**
     * 支持的通讯协议集合
     *
     * @param type1
     * @param type2
     * @return
     */
    private Set<String> newHashSet(String type1, String type2) {
        Set<String> set = new HashSet<>();
        set.add(type1);
        set.add(type2);
        return set;
    }

    /**
     * 安全模式，这里指定token通过Authorization头请求头传递
     * 通过 securitySchemes 来配置全局参数，这里的配置是一个名为 Authorization 的请求头（OAuth2 中需要携带的请求头）。
     */
    private List<SecurityScheme> securitySchemes() {
        List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
        apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
        return apiKeyList;
    }

    /**
     * 安全上下文
     * securityContexts 则用来配置有哪些请求需要携带 Token，这里我们配置了所有请求
     */
    private List<SecurityContext> securityContexts() {
        List<SecurityContext> securityContexts = new ArrayList<>();
        securityContexts.add(
                SecurityContext.builder()
                        .securityReferences(defaultAuth())
                        .operationSelector(o -> o.requestMappingPattern().matches("/.*"))
                        .build());
        return securityContexts;
    }

    /**
     * 默认的安全上引用
     */
    private List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        List<SecurityReference> securityReferences = new ArrayList<>();
        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
        return securityReferences;
    }
}
